<template>
      <div class="header">
      <span>11</span>
    </div>
  <div class="container">

    <h1 class="title">文件上传</h1>
    <div class="upload-section">
      <h2>普通上传</h2>
      <div class="file-input">
        <label for="singleFile">选择文件:</label>
        <input type="file" id="singleFile" @change="handleSingleFileUpload" />
      </div>
      <button @click="uploadSingleFile" :disabled="!singleFile">上传</button>
    </div>
    <div class="upload-section">
      <h2>分块上传</h2>
      <div class="file-input">
        <label for="chunkFile">选择文件:</label>
        <input type="file" id="chunkFile" @change="handleChunkFileSelect" />
      </div>
      <button @click="startChunkUpload" :disabled="!chunkFile">上传</button>
    </div>
    <p v-if="progress" class="progress">{{ progress }}%</p>
  </div>
</template>

<script setup>
import { ref } from "vue";
import CryptoJS from "crypto-js";
import {
  simpleFileUploadApi,
  InitiateMultipartUploadApi,
  UploadMultipartApi,
  CompleteUploadApi,
} from "@/api/file.js";

const singleFile = ref(null);
const chunkFile = ref(null);
const progress = ref(0);

const handleSingleFileUpload = (event) => {
  singleFile.value = event.target.files[0];
};

const handleChunkFileSelect = (event) => {
  chunkFile.value = event.target.files[0];
};

const uploadSingleFile = async () => {
  const singleFile = document.getElementById("singleFile").files[0]; // 获取文件
  if (!singleFile) {
    alert("请选择一个文件");
    return;
  }

  try {
    const response = await simpleFileUploadApi("admin", singleFile);

    if (response.status === 200) {
      alert("文件上传成功");
    } else {
      alert("文件上传失败");
    }
  } catch (error) {
    console.error("上传失败:", error);
    alert("文件上传失败");
  }
};

const startChunkUpload = async () => {
  if (!chunkFile.value) {
    alert("请选择一个文件");
    return;
  }

  const chunkSize = 1024 * 1024 * 5; // 每个分块大小为5MB
  const totalChunks = Math.ceil(chunkFile.value.size / chunkSize);

  console.log("分块数量:", totalChunks);
  // 计算文件的完整SHA-1哈希值
  const fileHash = await calculateFileSha1(chunkFile.value, chunkSize);
  const fileSize = chunkFile.value.size;
  // 发送初始化请求

  const initResponse = await InitiateMultipartUploadApi(
    fileHash,
    chunkFile.value.name,
    "root",
    fileSize
  );

  const uploadID = initResponse.data.uploadID;

  // 逐个上传分块
  for (let i = 0; i < totalChunks; i++) {
    const start = i * chunkSize;
    const end = Math.min(start + chunkSize, chunkFile.value.size);
    const chunk = chunkFile.value.slice(start, end);
    console.log("上传分块:", i);

    const response = await UploadMultipartApi(
      i.toString(),
      "root", // 请替换为实际用户名
      uploadID,
      chunk
    );

    if (response.status !== 200) {
      throw new Error("分块上传失败");
    }

    // 更新进度
    progress.value = ((i + 1) / totalChunks) * 100;
  }

  // 发送合并请求

  const response = await CompleteUploadApi(
    fileHash,
    chunkFile.value.name,
    "root",
    chunkFile.value.size,
    uploadID
  );
  if (response.status === 200) {
    alert("文件上传并合并成功");
  } else {
    alert("文件合并失败");
  }
};

const calculateFileSha1 = (file, chunkSize = 5 * 1024 * 1024) => { // 每个分块大小为5MB
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    let offset = 0;
    let sha1 = CryptoJS.algo.SHA1.create(); // 初始化 SHA1 哈希对象

    const readNextChunk = () => {
      const blob = file.slice(offset, offset + chunkSize);
      if (blob.size === 0) {
        // 文件读取完毕
        resolve(sha1.finalize().toString(CryptoJS.enc.Hex));
        return;
      }

      fileReader.readAsArrayBuffer(blob);
    };

    fileReader.onload = (e) => {
      const arrayBuffer = e.target.result;
      const wordArray = CryptoJS.lib.WordArray.create(arrayBuffer);
      sha1.update(wordArray); // 更新 SHA1 哈希对象
      offset += chunkSize;
      readNextChunk(); // 读取下一个分块
    };

    fileReader.onerror = () => {
      reject(new Error("读取文件失败"));
    };

    // 开始读取第一个分块
    readNextChunk();
  });
};
</script>

<style scoped>
/* 添加一些基本样式 */
.header{
  color: #dd1818;
}

.container {
  max-width: 700px;
  margin: 0 auto;
  padding: ¼em;
  font-family: Arial, sans-serif;
}

.title {
  text-align: center;
  margin-bottom: 1rem;
}

.upload-section {
  margin-bottom: 2rem;
  border: 1px solid #ddd;
  padding: 1rem;
  border-radius: 5px;
  background-color: #f9f9f9;
}

.upload-section h2 {
  margin-top: 0;
  margin-bottom: 0.5rem;
  font-size: 1.2em;
}

.file-input {
  display: flex;
  align-items: center;
  margin-bottom: 0.5rem;
}

.file-input label {
  margin-right: 0.5rem;
  font-size: 0.9em;
}

.file-input input[type="file"] {
  padding: 0.5em;
  border: 1px solid #ccc;
  border-radius: 3px;
}

button {
  padding: 0.5em 1em;
  border: none;
  border-radius: ¾em;
  background-color: #007bff;
  color: white;
  cursor: pointer;
  transition: background-color 0.3s;
}

button:hover {
  background-color: #0056b3;
}

button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.progress {
  text-align: center;
  font-size: 1.2em;
  font-weight: bold;
  color: #007bff;
}
</style>